Qt 事件与信号槽

1. 概述

  • 事件机制比信号槽更底层. 在事件中会默认的发送相应信号, 所以一般使用, 只需操作信号槽即可.
  • 当我们需要自定义组件修改现有组件的行为时, 就需要从事件的层面着手了.

2. 区别

  • 信号槽: 其针对的是对象与对象之间的连接. 当信号发射后, 与其相连的槽函数总是会被执行的.
  • 事件: 可以经过消息队列传输, 也可直接传输. 在传输过程中, 可经过事件过滤器和事件处理函数等手段来干预其.

3. 联系

  • 跨线程的信号槽机制是通过事件机制完成的.
  • 查看相关 Qt 源码可了解调用过程:

    • 以下情况的信号槽连接会通过 poseEvent()实现:
      - 信号槽为 `Qt::AutoConnection` 连接模式下
          - 发送信号线程非当前线程时  或  信号与槽不在同一线程
      - 信号槽为 `Qt::QueuedConnection` 连接模式下
      
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // (自动连接模式 && (信号线程非本线程 || 信号与槽非同一线程) || 对列连接模式)
    if ((c->connectionType == Qt::AutoConnection
       && (currentThreadData != sender->d_func()->threadData
       || receiver->d_func()->threadData != sender->d_func()->threadData))
       || (c->connectionType == Qt::QueuedConnection))
    {
    queued_activate(sender, signal, *c, argv);
    continue;
    }
    // 阻塞对列模式
    else if (c->connectionType == Qt::BlockingQueuedConnection)
    {
    blocking_activate(sender, signal, *c, argv);
    continue;
    }

    // 其中 queued_activate 会调用 :
    QCoreApplication::postEvent(c.receiver, new QMetaCallEvent(c.method, sender, signal, nargs, types, args, semaphore));

— 道理越辩越明, 欢迎留言讨论. —

0%